package com.lyw.GeoLocationClient.service;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.utils.DistanceUtil;
import com.easemob.applib.utils.HXPreferenceUtils;
import com.lyw.GeoLocationClient.App;
import com.lyw.GeoLocationClient.utils.LocationCallback;
import timber.log.Timber;

import java.util.LinkedList;

import static com.lyw.GeoLocationClient.utils.LogUtils.LOGD;


public class LBSLocation {

    private static LBSLocation location = null;

    private static int SCAN_SPAN = 10000;
    private static final double VALID_MIN_DISTANCE = 20;
    private static final double VALID_MAX_DISTANCE = SCAN_SPAN/1000*200;

    public LocationClient mLocationClient = null;
    private BDLocation mCurrlocation = null;

    private LocationCallback locationCallback;
    private BDLocation mLastLocation; //防止重复数据

    private MyAlarmManager alarManager;
    private LinkedList<BDLocation> locationLinkedList;

    public static LBSLocation getInstance(Context context, LocationCallback callback) {

        if (location == null) {
            location = new LBSLocation(context, callback);
        }
        return location;
    }

    private LBSLocation(Context context, LocationCallback callback) {
        mLocationClient = new LocationClient(context);
        MyLocationListenner myListener = new MyLocationListenner();
        mLocationClient.registerLocationListener(myListener);
        this.locationCallback = callback;
        alarManager = new MyAlarmManager(context);
        locationLinkedList = new LinkedList<BDLocation>();
        startLocation();

        SCAN_SPAN = HXPreferenceUtils.getInstance().getUpdateSpan() * 1000;
    }

    /**
     * 开始定位请求，结果在回调中
     */
    private void startLocation() {
        LOG("startLocation...");

        mLocationClient.start();

        LocationClientOption option = new LocationClientOption();
        option.setOpenGps(true);
        option.setIsNeedAddress(true);// 返回的定位结果包含地址信息
        option.setCoorType("bd09ll");// 返回的定位结果是百度经纬度,默认值gcj02
        option.disableCache(true);// 禁止启用缓存定位
        if (App.isAdmin()) {
            SCAN_SPAN = 0;
        }
        option.setScanSpan(SCAN_SPAN); //设置发起定位请求的间隔时间为(ms)
        option.setNeedDeviceDirect(true);

        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);//高精度
        mLocationClient.setLocOption(option);
        mLocationClient.requestLocation();

        alarManager.startAlarm(SCAN_SPAN >> 3);
    }

    public void restart() {
        if (!mLocationClient.isStarted()) {
            mLocationClient.start();
        }
        Timber.d("restart");
        mLocationClient.requestLocation();
//        alarManager.startAlarm(SCAN_SPAN>>1);
    }

    public void stop() {
        LOG("stop");
        if (mLocationClient.isStarted() && mCurrlocation != null) {
            mLocationClient.stop();
        }
        alarManager.stop();
    }

    public BDLocation getCurrlocation() {
        return mCurrlocation;
    }

    public class MyLocationListenner implements BDLocationListener {
        @Override
        public void onReceiveLocation(BDLocation location) {
            if (location == null)
                return;
            LOG("onReceiveLocation..." + location.getAddrStr());
            if (location.getAddrStr() == null) {
                return;
            }
            mCurrlocation = location;
            if (mLastLocation != null) {
                LatLng newLatLng = new LatLng(location.getLatitude(),
                        location.getLongitude());
                LatLng oldLatlng = new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude());

                double distance = DistanceUtil.getDistance(newLatLng, oldLatlng);
                LOG("distance is  " + distance);
                if ((distance < VALID_MIN_DISTANCE || distance > VALID_MAX_DISTANCE)) {
                    return;
                }
            }

            locationLinkedList.add(location);
            if (locationCallback != null) {
                locationCallback.onReceiveLocation(location);
            }
            mLastLocation = location;
        }
    }

    public LinkedList<BDLocation> getLocationLinkedList() {
        return locationLinkedList;
    }

    public void LOG(String msg) {
        LOGD(LBSLocation.class, msg);
    }
}
